package com.yuyou.fn.tms.service.impl;

import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.google.common.collect.Lists;
import com.yuyou.fn.common.constant.ClassLevelEnum;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.platform.entity.City;
import com.yuyou.fn.platform.entity.District;
import com.yuyou.fn.platform.entity.Province;
import com.yuyou.fn.platform.service.ICityService;
import com.yuyou.fn.platform.service.IDistrictService;
import com.yuyou.fn.platform.service.IProvinceService;
import com.yuyou.fn.settlement.entity.NewPayRecord;
import com.yuyou.fn.settlement.service.INewPayRecordService;
import com.yuyou.fn.tms.service.IDataSyncService;
import com.yuyou.fn.tms.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;

@Service
public class DataSyncServiceImpl implements IDataSyncService {

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IAttendClassLectureService attendClassLectureService;

    @Resource
    private IClassLectureService classLectureService;

    @Resource
    private IProvinceService provinceService;

    @Resource
    private ICityService cityService;

    @Resource
    private IDistrictService districtService;

    @Resource
    private IBaseGradeService baseGradeService;

    @Resource
    private IProductService productService;

    @Resource
    private IBaseSubjectService baseSubjectService;

    @Resource
    private ICourseTemplateService courseTemplateService;

    @Resource
    private IStudentService studentService;

    @Resource
    private IStudentSchoolService studentSchoolService;



    @Resource
    private IChargeSettingService chargeSettingService;

    @Resource
    private IClassTeacherService classTeacherService;

    @Resource
    private ITeacherService teacherService;

    @Resource
    private IStudentRegService studentRegService ;

    @Resource
    private INewPayRecordService newPayRecordService ;

    @Resource
    private ICourseOrderService courseOrderService;

    @Resource
    private ICampusService campusService;

    @Resource
    private IPeriodSegmentService periodSegmentService;

    /*某些项只给这些区域数据*/
    private List<Long> areaTeamIds=Arrays.asList(564701030634225664L);

    /*区域和城市的关系*/
    private Map<Long,Long> areaTeamCityRelativeMap=new HashMap<>();


    @PostConstruct
    private void init(){
        /*广州区域对应广州市*/
        areaTeamCityRelativeMap.put(564701030634225664l,1l);
    }

    @Override
    public PageQueryResult<TmsCourseClass> queryTmsCourseClass(PageRequestParam requestParam) {

        Example<CourseClass> example = CourseClass.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        fillAreaTeamsCondition(criteria);
        Page<CourseClass> page = courseClassService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        Map<Long,City> cityMap=cityService.findAllCityMapById();
        List<Long> campusIds=Utils.removeDuplicate(BeanUtils.toList(page.getRecords(),"campusId"));
        List<Campus> campusList=campusService.findByIds(campusIds);

        List<Long> periodIds=Utils.removeDuplicate(BeanUtils.toList(page.getRecords(),"periodId"));
        List<PeriodSegment> periodSegmentList=periodSegmentService.findByPeriodSegmentListByPeriodIds(periodIds);
        Map<String,PeriodSegment> periodSegmentMap=new HashMap<>();
        for (PeriodSegment periodSegment:periodSegmentList){
            String key=periodSegment.getPeriodId()+"_"+periodSegment.getSegmentNo();
            periodSegmentMap.put(key,periodSegment);
        }

        List<Long> productIds=Utils.removeDuplicate(BeanUtils.toList(page.getRecords(),"productId"));
        List<Product> productList=productService.findByIds(productIds);
        Map<Long, Product> productMap = BeanUtils.toMap(productList, "productId");

        Map<Long, Campus> campusMap = BeanUtils.toMap(campusList, "campusId");
        Map<String,District> districtMap=districtService.findAllMapByProvinceCityDistrictName();
        List<TmsCourseClass> list = Lists.transform(page.getRecords(), item -> {
            String key=item.getPeriodId()+"_"+item.getSegmentNo();
            PeriodSegment periodSegment=periodSegmentMap.get(key);
            Long cityId=areaTeamCityRelativeMap.get(item.getAreaTeamId());
            City city=cityMap.get(cityId);
            District district=null;
            Campus campus=campusMap.get(item.getCampusId());
            if (campus!=null){
                if (StringUtils.isNotEmpty(campus.getDistrict()) && StringUtils.isNotEmpty(campus.getCity()) && StringUtils.isNotEmpty(campus.getProvince())){
                    String districtKey=campus.getProvince().replaceAll("省","")+"_"+campus.getCity().replaceAll("市","")+"_"+campus.getDistrict();
                    district=districtMap.get(districtKey);
                }
            }
            Product product=productMap.get(item.getProductId());
            return new TmsCourseClass(item,city,district,periodSegment,product);
        });

        return new PageQueryResult<>(page.getTotal(),list);
    }


    @Override
    public PageQueryResult<TmsClassDegree> queryTmsClassDegree(PageRequestParam requestParam) {
        Example<CourseClass> example = CourseClass.createExample();
        example.orderBy("degreeUpdateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,"degreeUpdateTime" );
        fillAreaTeamsCondition(criteria);
        Page<CourseClass> page = courseClassService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());

        List<TmsClassDegree> list = Lists.transform(page.getRecords(), item -> {

            return new TmsClassDegree(item);
        });

        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsClassLecture> queryTmsClassLecture(PageRequestParam requestParam) {
        Example<AttendClassLecture> example = AttendClassLecture.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        fillAreaTeamsCondition(criteria);
        Page<AttendClassLecture> page = attendClassLectureService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());

        List<Long> classIds= Utils.removeDuplicate(BeanUtils.toList(page.getRecords(),"classId"));
        List<CourseClass> courseClassList=courseClassService.findByIds(classIds,CourseClass.BASE_FIELDS);
        Map<Long,CourseClass> courseClassMap=BeanUtils.toMap(courseClassList,"classId");

        List<TmsClassLecture> list = Lists.transform(page.getRecords(), item -> {
            final CourseClass courseClass=courseClassMap.get(item.getClassId());
            return new TmsClassLecture(item,courseClass);
        });

        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsProvince> queryTmsProvince(PageRequestParam requestParam) {
        Example<Province> example = Province.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        Page<Province> page = provinceService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());

        List<TmsProvince> list = Lists.transform(page.getRecords(), item -> {

            return new TmsProvince(item);
        });

        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsCity> queryTmsCity(PageRequestParam requestParam) {
        Example<City> example = City.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        Page<City> page = cityService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        List<TmsCity> list = Lists.transform(page.getRecords(), item -> {
            return new TmsCity(item);
        });

        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsDistrict> queryTmsDistrict(PageRequestParam requestParam) {
        Example<District> example = District.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        Page<District> page = districtService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        List<TmsDistrict> list = Lists.transform(page.getRecords(), item -> {
            return new TmsDistrict(item);
        });

        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsCampus> queryTmsCampus(PageRequestParam requestParam) {
        Example<Campus> example = Campus.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("state",1);
        fillCondition(criteria,requestParam,null );
        fillAreaTeamsCondition(criteria);
        Page<Campus> page = campusService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        Map<String,City> cityMap=cityService.findAllCityMapByProvinceNameCityName();
        Map<String,District> districtMap=districtService.findAllMapByProvinceCityDistrictName();
        Map<String,Province> provinceMap=provinceService.findAllProvinceMapByProvinceName();
        List<TmsCampus> list = Lists.transform(page.getRecords(), item -> {
            Province province=null;
            City city=null;
            District district=null;
            if (StringUtils.isNotEmpty(item.getProvince()) && StringUtils.isNotEmpty(item.getCity()) && StringUtils.isNotEmpty(item.getDistrict())){
                String provinceKey=item.getProvince().replaceAll("省","");
                String cityKey=provinceKey+"_"+item.getCity().replaceAll("市","");
                String districtKey=cityKey+"_"+item.getDistrict();
                province=provinceMap.get(provinceKey);
                city=cityMap.get(cityKey);
                district=districtMap.get(districtKey);
            }

            return new TmsCampus(item,province,city,district);
        });
        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsGrade> queryTmsGrade(PageRequestParam requestParam) {
        List<BaseGrade> baseGradeList = baseGradeService.findAllOrderGrade();
        List<TmsGrade> list = Lists.transform(baseGradeList, item -> {
            return new TmsGrade(item);
        });
        return new PageQueryResult<>(baseGradeList.size(),list);
    }

    @Override
    public PageQueryResult<TmsLevel> queryTmsLevel(PageRequestParam requestParam) {
        List<TmsLevel> list=new ArrayList<>();
        for (ClassLevelEnum classLevelEnum:ClassLevelEnum.values()){
            if (classLevelEnum.ordinal()==0){
                continue;
            }
            TmsLevel tmsLevel=new TmsLevel();
            tmsLevel.setgId((long)classLevelEnum.ordinal());//层级id
            tmsLevel.setgName(classLevelEnum.name());//层次名称
            tmsLevel.setgCode(classLevelEnum.ordinal()+"");//层级编号
            tmsLevel.setgValue(classLevelEnum.ordinal()+"");//层级值(课程分层精英>培优>提高)
            tmsLevel.setModifyTime(TimeUtils.now());//最后修改时间
            tmsLevel.setStatus(0);//状态(0:使用,1:冻结)
            tmsLevel.setIsDelete(0);//是否删除(0否,1是)
            list.add(tmsLevel);
        }
        return new PageQueryResult<>(list.size(),list);
    }

    @Override
    public PageQueryResult<TmsProduct> queryTmsProduct(PageRequestParam requestParam) {
        Example<Product> example = Product.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        fillAreaTeamsCondition(criteria);
        Page<Product> page = productService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());

        List<TmsProduct> list = Lists.transform(page.getRecords(), item -> {
            return new TmsProduct(item);
        });
        return new PageQueryResult<>(page.getTotal(),list);

    }

    @Override
    public PageQueryResult<TmsSubject> queryTmsSubject(PageRequestParam requestParam) {
        List<BaseSubject> baseSubjectList = baseSubjectService.findAllFromCache();
        List<TmsSubject> list = Lists.transform(baseSubjectList, item -> {
            return new TmsSubject(item);
        });
        return new PageQueryResult<>(baseSubjectList.size(),list);
    }

    @Override
    public PageQueryResult<TmsCourseTemplate> queryTmsCourseTemplate(PageRequestParam requestParam) {
        Example<CourseTemplate> example=CourseTemplate.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        fillAreaTeamsCondition(criteria);
        Page<CourseTemplate> page = courseTemplateService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        Map<Long,City> cityMap=cityService.findAllCityMapById();
        List<TmsCourseTemplate> list = Lists.transform(page.getRecords(), item -> {
            Long cityId=areaTeamCityRelativeMap.get(item.getAreaTeamId());
            City city=cityMap.get(cityId);
            return new TmsCourseTemplate(item,city);
        });
        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsStudent> queryTmsStudent(PageRequestParam requestParam) {
        Example<Student> example=Student.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        Page<Student> page = studentService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        Map<String,City> cityMap=cityService.findAllCityMapByProvinceNameCityName();
        Map<String,District> districtMap=districtService.findAllMapByProvinceCityDistrictName();
        List<TmsStudent> list = Lists.transform(page.getRecords(), item -> {
            String location=item.getLocation();
            City city=null;
            District district=null;
            if (StringUtils.isNotEmpty(location)){
                String[] locations = location.split(" ");
                if (locations.length>=3){
                    String cityKey=locations[0].replaceAll("省","")+"_"+locations[1].replaceAll("市","");
                    String districtKey=cityKey+"_"+locations[2];
                    city=cityMap.get(cityKey);
                    district=districtMap.get(districtKey);
                }
            }
            return new TmsStudent(item,city,district);
        });
        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsSchool> queryTmsSchool(PageRequestParam requestParam) {
        Example<StudentSchool> example=StudentSchool.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        Page<StudentSchool> page = studentSchoolService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());

        Map<String, Province> provinceMap = provinceService.findAllProvinceMapByProvinceName();
        Map<String,City> cityMap=cityService.findAllCityMapByProvinceNameCityName();
        List<TmsSchool> list = Lists.transform(page.getRecords(), item -> {
            Province province=null;
            City city=null;
            if (StringUtils.isNotEmpty(item.getProvince())){
                String provinceKey=item.getProvince().replaceAll("省","");
                province=provinceMap.get(provinceKey);
                if (StringUtils.isNotEmpty(item.getCity())){
                    String cityKey=provinceKey+"_"+item.getCity().replaceAll("市","");
                    city=cityMap.get(cityKey);
                }
            }
            return new TmsSchool(item,province,city);
        });
        return new PageQueryResult<>(page.getTotal(),list);
    }



    @Override
    public PageQueryResult<TmsChargeSetting> queryTmsChargeSetting(PageRequestParam requestParam) {
        Example<ChargeSetting> example=ChargeSetting.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        fillAreaTeamsCondition(criteria);
        Map<Long,City> cityMap=cityService.findAllCityMapById();
        Page<ChargeSetting> page = chargeSettingService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        List<TmsChargeSetting> list = Lists.transform(page.getRecords(), item -> {
            Long cityId=areaTeamCityRelativeMap.get(item.getAreaTeamId());
            City city=cityMap.get(cityId);
            return new TmsChargeSetting(item,city);
        });
        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsClassTeacher> queryTmsClassTeacher(PageRequestParam requestParam) {
        Example<ClassTeacher> example=ClassTeacher.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        fillAreaTeamsCondition(criteria);
        Page<ClassTeacher> page = classTeacherService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        List<TmsClassTeacher> list = Lists.transform(page.getRecords(), item -> {

            return new TmsClassTeacher(item);
        });
        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsTeacher> queryTmsTeacher(PageRequestParam requestParam) {
        Example<Teacher> example=Teacher.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam,null );
        fillAreaTeamsCondition(criteria);
        Page<Teacher> page = teacherService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());
        List<TmsTeacher> list = Lists.transform(page.getRecords(), item -> {
            return new TmsTeacher(item);
        });
        return new PageQueryResult<>(page.getTotal(),list);
    }

    @Override
    public PageQueryResult<TmsReg> queryTmsReg(PageRequestParam requestParam) {

        Example<StudentReg> example=StudentReg.createExample();
        example.orderBy("updateTime");
        Example.Criteria criteria = example.createCriteria();
        fillCondition(criteria,requestParam ,null);
        fillAreaTeamsCondition(criteria);

        Page<StudentReg> page = studentRegService.findPageByExample(example, requestParam.getPageIndex(), requestParam.getPageSize());

        List<Long> courseOrderIds = Utils.unique(BeanUtils.toList(page.getRecords(), "courseOrderId"));

        List<CourseOrder> courseOrders = courseOrderService.findByIds(courseOrderIds);
        List<NewPayRecord> newPayRecords = newPayRecordService.findByBusOrderIds(courseOrderIds);
        Map<Long,CourseOrder> courseOrderId2CourseOrder = BeanUtils.toMap(courseOrders,"courseOrderId");
        Map<Long,List<NewPayRecord>> busOrderId2NewPayRecords  = BeanUtils.toGroup(newPayRecords,"busOrderId");
        List<TmsReg> list = Lists.transform(page.getRecords(), item -> {
            CourseOrder courseOrder = courseOrderId2CourseOrder.get(item.getCourseOrderId());
            List<NewPayRecord> payRecords = busOrderId2NewPayRecords.get(item.getCourseOrderId());
            TmsRegOrder tmsRegOrder = new TmsRegOrder(courseOrder);
            tmsRegOrder.setOrderCounselorId(item.getCounselorId());
            tmsRegOrder.setOrderCounselorName(item.getCounselorName());
            return new TmsReg(item,tmsRegOrder,payRecords);
        });
        return new PageQueryResult<>(page.getTotal(),list);
    }

    private void fillCondition(Example.Criteria criteria, PageRequestParam requestParam,String queryTime) {
        if (StringUtils.isEmpty(queryTime)){
            queryTime="updateTime";
        }
        criteria.andLessThanOrEqualTo(queryTime,requestParam.getEndTime()).andGreaterThanOrEqualTo(queryTime,requestParam.getStartTime());
        if(requestParam.getModifyTime() != null ){
            criteria.andGreaterThanOrEqualTo(queryTime,requestParam.getModifyTime());
        }

    }

    private void fillAreaTeamsCondition(Example.Criteria criteria) {
        criteria.andIn("areaTeamId", areaTeamIds);

    }
}
